/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: EditUserPresenter.java
 * Date: 02/03/2011
 */

package com.ingenius.sau.client.presenter;

import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ingenius.sau.client.AppController;
import com.ingenius.sau.client.Constants;
import com.ingenius.sau.client.event.ListUsersEvent;
import com.ingenius.sau.client.service.UsersServiceAsync;
import com.ingenius.sau.client.view.Display;
import com.ingenius.sau.shared.model.users.Person;
import com.ingenius.sau.shared.model.users.Role;
import com.ingenius.sau.shared.model.users.User;

/**
 * Class <strong>EditUserPresenter</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class EditUserPresenter implements EditPresenter {

	public interface EditUserDisplay extends Display {

		String getUsername();

		void setUsername(String username);

		String getPassword();

		void setPassword(String password);

		String getPasswordConfirm();

		void setPasswordConfirm(String confirm);

		String getSelectedRoleId();

		void setFirstname(String firstname);

		String getFirstname();

		void setLastname(String lastname);

		String getLastname();

		void setSelectedRoleId(String roleId);

		void setRoles(List<Role> roles);

		void show();

		void hide();
	}

	private final HandlerManager eventBus;
	private final UsersServiceAsync rpcService;
	private final EditUserDisplay display;
	private User user;

	public EditUserPresenter(HandlerManager eventBus,
			UsersServiceAsync rpcService, EditUserDisplay display, String userId) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		display.setPresenter(this);
		loadRoles();

		if (userId == null) {
			user = new User();

		} else {
			loadBean(userId);
		}

	}

	private void loadRoles() {
		rpcService.loadAllRoles(new AsyncCallback<List<Role>>() {
			@Override
			public void onSuccess(List<Role> result) {
				display.setRoles(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Error loading roles. "
						+ caught.getMessage());
			}
		});
	}

	private void loadBean(String userId) {
		AppController.setStatusMessage("Loading...");
		rpcService.getUser(userId, new AsyncCallback<User>() {
			@Override
			public void onSuccess(User result) {
				if (result == null) {
					onFailure(new Throwable("Database error"));
					return;
				}
				user = result;

				display.setUsername(user.getUsername());
				display.setPassword(user.getPassword());
				display.setPasswordConfirm(user.getPassword());
				display.setSelectedRoleId(user.getRole().getId());
				display.setFirstname(user.getPerson().getFirstname());
				display.setLastname(user.getPerson().getLastname());
				hideStatusMessage();
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_GET + User.class.getName(),
						caught);
				user = new User();
				// TODO i18n
				String failedMessage = "Failed to retrieve user";
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.client.presenter.EditPresenter#doSaveOrUpdate()
	 */
	@Override
	public void doSaveOrUpdate() {
		user.setUsername(display.getUsername());
		user.setPassword(display.getPassword());
		user.setPasswordChangeRequired(false);
		user.setLastAdmission(new Date());
		user.setRole(new Role(display.getSelectedRoleId()));

		Person person = (user.getPerson() == null) ? new Person() : user
				.getPerson();
		person.setFirstname(display.getFirstname());
		person.setLastname(display.getLastname());
		user.setPerson(person);

		// TODO i18n
		final String failedMessage = "Failed to save user";
		final String successMessage = "User saved sucessfully";

		display.hide();
		AppController.setStatusMessage("Saving...");
		rpcService.saveOrUpdateUser(user, new AsyncCallback<Boolean>() {
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					eventBus.fireEvent(new ListUsersEvent());
					display.showInfo(successMessage);
					hideStatusMessage();

				} else {
					onFailure(new Throwable("Database error"));
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_SAVE + User.class.getName(),
						caught);
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.ingenius.sau.client.presenter.Presenter#go(com.google.gwt.user.client
	 * .ui.HasWidgets)
	 */
	@Override
	public void go(HasWidgets container) {
		display.show();
	}

}
